"""
工具3：AI评分工具（核心工具）
功能：使用LLM对候选人进行评分并生成推荐理由
"""
import json
import logging
import os
from typing import Dict, Optional, Any
from langchain.tools import BaseTool
from pydantic import Field
from openai import OpenAI

logger = logging.getLogger(__name__)


class AIScoringTool(BaseTool):
    """
    AI评分工具
    
    功能：
    - 综合评估候选人与职位的匹配度
    - 生成详细的推荐理由
    - 识别潜在风险点
    """
    
    name: str = "ai_scoring_tool"
    description: str = """
        使用AI对候选人进行智能评分并生成推荐理由。
        
        🤖 核心能力：
        - 综合评分（0-100分）
        - 生成3-5条推荐理由
        - 识别风险提示
        
        📥 输入参数（JSON字符串）：
        {
            "resume_info": {
                "name": "张三",
                "skills": ["Python", "Django"],
                "experience": "5年",
                "education": "本科"
            },
            "job_requirements": {
                "title": "Python工程师",
                "required_skills": ["Python", "Django", "MySQL"],
                "experience_needed": "3-5年",
                "education_needed": "本科"
            }
        }
        
        📤 返回格式（JSON字符串）：
        {
            "success": true,
            "data": {
                "score": 85,
                "level": "优秀",
                "reasons": [
                    "技能完美匹配：Python、Django经验丰富",
                    "工作年限符合要求：5年经验",
                    "学历达标：本科学历"
                ],
                "risks": ["暂无明显风险"],
                "suggestion": "建议优先安排面试"
            },
            "message": "评分完成"
        }
        """
    
    # 声明llm_client字段（Pydantic要求）
    llm_client: Optional[Any] = Field(default=None, exclude=True)
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 初始化LLM客户端
        object.__setattr__(self, 'llm_client', self._init_llm())
    
    def _init_llm(self):
        """初始化LLM客户端"""
        try:
            api_key = os.getenv("DASHSCOPE_API_KEY")
            if not api_key:
                logger.warning("DASHSCOPE_API_KEY未设置")
                return None
            
            return OpenAI(
                api_key=api_key,
                base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
            )
        except Exception as e:
            logger.error(f"LLM初始化失败: {str(e)}")
            return None
    
    def _run(self, tool_input: str) -> str:
        """
        执行AI评分
        
        Args:
            tool_input: 输入参数，可以是：
                - JSON字符串：{"resume_info": {...}, "job_requirements": {...}}
                - 或分别的参数
        
        Returns:
            JSON字符串格式的评分结果
        """
        try:
            # 1. 参数解析
            if isinstance(tool_input, str):
                try:
                    # 尝试解析为JSON
                    input_dict = json.loads(tool_input)
                except json.JSONDecodeError:
                    return self._error_response("输入必须是有效的JSON格式")
            elif isinstance(tool_input, dict):
                input_dict = tool_input
            else:
                return self._error_response(f"不支持的输入类型: {type(tool_input)}")
            
            # 2. 提取resume_info和job_requirements
            resume_info = input_dict.get('resume_info')
            job_requirements = input_dict.get('job_requirements')
            
            if not resume_info or not job_requirements:
                return self._error_response("必须提供resume_info和job_requirements")
            
            # 3. 确保是字典格式
            if isinstance(resume_info, str):
                resume_dict = json.loads(resume_info)
            else:
                resume_dict = resume_info
            
            if isinstance(job_requirements, str):
                job_dict = json.loads(job_requirements)
            else:
                job_dict = job_requirements
            
            # 4. 使用LLM进行评分
            if self.llm_client:
                scoring_result = self._llm_scoring(resume_dict, job_dict)
            else:
                # 降级：使用规则评分
                scoring_result = self._rule_based_scoring(resume_dict, job_dict)
            
            logger.info(f"评分完成: score={scoring_result['score']}")
            return self._success_response(scoring_result, "评分完成")
            
        except json.JSONDecodeError as e:
            return self._error_response(f"JSON解析失败: {str(e)}")
        except Exception as e:
            logger.error(f"AI评分失败: {str(e)}", exc_info=True)
            return self._error_response(f"评分失败: {str(e)}")
    
    def _llm_scoring(self, resume: Dict, job: Dict) -> Dict:
        """
        使用LLM进行评分
        """
        prompt = f"""你是专业的HR顾问。请根据简历和职位要求，给出评分和理由。

简历信息：
- 姓名：{resume.get('name', '未知')}
- 技能：{', '.join(resume.get('skills', []))}
- 经验：{resume.get('experience', '未知')}
- 学历：{resume.get('education', '未知')}

职位要求：
- 职位：{job.get('title', '未知')}
- 所需技能：{', '.join(job.get('required_skills', []))}
- 经验要求：{job.get('experience_needed', '不限')}
- 学历要求：{job.get('education_needed', '不限')}

请按以下JSON格式返回评分结果：
{{
    "score": 85,
    "reasons": ["理由1", "理由2", "理由3"],
    "risks": ["风险点1"],
    "suggestion": "面试建议"
}}

要求：
1. score范围：60-100分
2. reasons：3-5条，每条20字内
3. risks：如无风险写["暂无明显风险"]
4. suggestion：一句话建议

请直接返回JSON，不要其他说明。"""
        
        try:
            response = self.llm_client.chat.completions.create(
                model="qwen-plus",
                messages=[{"role": "user", "content": prompt}],
                temperature=0.3,
                max_tokens=500
            )
            
            content = response.choices[0].message.content.strip()
            
            # 提取JSON（可能包含markdown代码块）
            if '```json' in content:
                content = content.split('```json')[1].split('```')[0].strip()
            elif '```' in content:
                content = content.split('```')[1].split('```')[0].strip()
            
            result = json.loads(content)
            
            # 添加评级
            score = result.get('score', 70)
            result['level'] = self._get_level(score)
            
            return result
            
        except Exception as e:
            logger.error(f"LLM评分失败: {str(e)}")
            # 降级到规则评分
            return self._rule_based_scoring(resume, job)
    
    def _rule_based_scoring(self, resume: Dict, job: Dict) -> Dict:
        """
        规则评分（LLM不可用时的降级方案）
        """
        score = 60  # 基础分
        reasons = []
        risks = []
        
        # 技能匹配（40分）
        resume_skills = set([s.lower() for s in resume.get('skills', [])])
        required_skills = set([s.lower() for s in job.get('required_skills', [])])
        
        if required_skills:
            matched_skills = resume_skills & required_skills
            skill_score = (len(matched_skills) / len(required_skills)) * 40
            score += skill_score
            
            if matched_skills:
                reasons.append(f"✅ 技能匹配：{', '.join(matched_skills)}")
            else:
                risks.append("⚠️ 关键技能不匹配")
        
        # 经验匹配（30分）
        resume_exp = resume.get('experience', '')
        job_exp = job.get('experience_needed', '')
        
        if '年' in resume_exp and '年' in job_exp:
            # 简化：直接比较数字
            try:
                resume_years = int(''.join(filter(str.isdigit, resume_exp)))
                if '以上' in job_exp or '+' in job_exp:
                    job_years = int(''.join(filter(str.isdigit, job_exp)))
                    if resume_years >= job_years:
                        score += 30
                        reasons.append(f"✅ 工作年限符合要求：{resume_exp}")
                    else:
                        risks.append(f"⚠️ 工作年限不足，要求{job_exp}")
            except:
                pass
        
        # 学历匹配（10分）
        resume_edu = resume.get('education', '')
        job_edu = job.get('education_needed', '')
        
        edu_rank = {'博士': 5, '硕士': 4, '本科': 3, '大专': 2}
        resume_rank = edu_rank.get(resume_edu, 1)
        job_rank = edu_rank.get(job_edu, 1)
        
        if resume_rank >= job_rank:
            score += 10
            reasons.append(f"✅ 学历达标：{resume_edu}")
        else:
            risks.append(f"⚠️ 学历不符，要求{job_edu}")
        
        # 确保分数在60-100之间
        score = max(60, min(100, int(score)))
        
        if not risks:
            risks = ["暂无明显风险"]
        
        # 生成建议
        if score >= 85:
            suggestion = "建议优先安排面试"
        elif score >= 75:
            suggestion = "建议安排面试"
        elif score >= 70:
            suggestion = "可以考虑面试"
        else:
            suggestion = "建议谨慎考虑"
        
        return {
            "score": score,
            "level": self._get_level(score),
            "reasons": reasons if reasons else ["综合评估符合基本要求"],
            "risks": risks,
            "suggestion": suggestion
        }
    
    def _get_level(self, score: int) -> str:
        """根据分数获取评级"""
        if score >= 90:
            return "优秀"
        elif score >= 80:
            return "良好"
        elif score >= 70:
            return "合格"
        else:
            return "待提升"
    
    def _success_response(self, data: Dict, message: str) -> str:
        """成功响应"""
        return json.dumps({
            "success": True,
            "data": data,
            "message": message
        }, ensure_ascii=False)
    
    def _error_response(self, error: str) -> str:
        """失败响应"""
        return json.dumps({
            "success": False,
            "error": error,
            "message": "操作失败"
        }, ensure_ascii=False)
    
    async def _arun(self, *args, **kwargs):
        """异步执行（暂不实现）"""
        raise NotImplementedError("暂不支持异步调用")


